home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / tex / cut_past.zip / PASTE.C < prev    next >
Text File  |  1987-03-04  |  5KB  |  243 lines

  1. /*
  2.  * A version of paste. This is compatable with AT&T paste command SVR2.
  3.  *
  4.  * John Weald
  5.  *
  6.  */
  7. #include <stdio.h>
  8.  
  9. #define MAXLINE   1024            /* Max. allowed line length    */
  10. #define MAXFILES  12            /* Max. number of input files   */
  11.  
  12. extern exit();
  13.  
  14. main(argc, argv)
  15. int argc;
  16. char *argv[];
  17. {
  18.     extern int optind;
  19.     extern char *optarg;
  20.  
  21.     int c;                /* For getopt()            */
  22.     char conchars[MAXFILES];    /* The concatination characters */
  23.     int nconchars = 1;        /* The number of conchars[]    */
  24.     int serial = 0;            /* True if old type paste "-s"    */
  25.  
  26.     conchars[0] = '\t';
  27.  
  28.     while ((c = getopt(argc, argv, "sd:", "paste")) != EOF)
  29.     {
  30.         switch(c)
  31.         {
  32.            case 's':
  33.             /* Concatinate the same file serially */
  34.             serial++;
  35.             break;
  36.  
  37.            case 'd':
  38.             /* Use other than a single tab */
  39.             nconchars = setconcat(conchars, optarg);
  40.             break;
  41.  
  42.            default:
  43.             /* Does not return */
  44.             prusage();
  45.         }
  46.     }
  47.  
  48.  
  49.     if (serial)
  50.         spaste(&argv[optind], conchars, nconchars);
  51.     else
  52.         paste(&argv[optind], conchars, nconchars);
  53.     exit(0);
  54. /* NOTREACHED */
  55. }
  56.  
  57.  
  58.  
  59. /*
  60.  * paste()
  61.  *
  62.  * Do the actual paste.
  63.  */
  64. paste(files, con, ncons)
  65. char *files[];        /* Null terminated list of input files        */
  66. char con[];        /* The concatination characters            */
  67. char ncons;        /* The number of above                */
  68. {
  69.     char ibuf[MAXLINE+1];        /* The  input buffer        */
  70.     char obuf[MAXLINE];        /* The  output buffer        */
  71.     register char *iptr = ibuf;
  72.     register char *optr = obuf;
  73.     FILE *fps[MAXFILES];        /* One for each open file     */
  74.     int f;                /* Number of files opened    */
  75.     int allfiles;            /* Ditto            */
  76.     int inc;            /* True if concat. char. == '\0'*/
  77.     int ocount;            /* Output buffer char. count    */
  78.     char c;                /* The current concat. char    */
  79.     int i;
  80.  
  81.     /*
  82.      * Open all the input files, any filename of '-' means
  83.      * the standard input. No file name means standard input.
  84.      */
  85.     for (f = 0; files[f] != NULL; f++)
  86.     {
  87.         if (*files[f] == '-')
  88.             fps[f] = stdin;
  89.         else if ((fps[f] = fopen(files[f], "r")) == (FILE *)NULL)
  90.         {
  91.             fprintf(stderr, "Failed to open file %s\n", files[f]);
  92.             exit(1);
  93.         }
  94.         if (f >= MAXFILES)
  95.         {
  96.             fprintf(stderr, 
  97.                "Too many files. Maximum allowed is %d\n", MAXFILES);
  98.             exit(1);
  99.         }
  100.     } 
  101.     if (files[0] == NULL)
  102.     {
  103.         fps[0] = stdin;
  104.         f++;
  105.     }
  106.  
  107.     /*
  108.      * Read all lines until no more lines in any file.
  109.      */
  110.     allfiles = f;
  111.     while (f)
  112.     {
  113.         optr = obuf;
  114.         ocount = 0;
  115.         /*
  116.          * Join lines from all files.
  117.          *
  118.          * The concatination character may be '\0' which
  119.          * means no character. The variable inc is an indication
  120.          * of the concatination character being '\0', we need to
  121.          * if there is a concatination character to move up the
  122.          * output buffer.
  123.          *
  124.          * The concatination characters are used in a round robin
  125.          * list.
  126.          */
  127.  
  128.         for (inc = 0, i = 0; i < allfiles; i++)
  129.         {
  130.             iptr = ibuf;
  131.             optr += inc;
  132.             /* To save repeated evaluation */
  133.             c = con[i % ncons];
  134.             inc = c == '\0' ? 0 : 1;
  135.  
  136.             if (fps[i] == (FILE *)NULL)
  137.             {
  138.                 /* No more lines in this file. */
  139.  
  140.                 *optr = c;
  141.                 continue;
  142.             }
  143.             if (fgets(ibuf, sizeof(ibuf), fps[i]) == NULL)
  144.             {
  145.                 /* Reached EOF - finished with the file */
  146.                 fclose(fps[i]);
  147.                 fps[i] = (FILE *)NULL;
  148.                 *optr = c;
  149.                 f--;
  150.                 continue;
  151.             }
  152.  
  153.             /*
  154.              * Replace the newline with the concatination character.
  155.              * There is no need to look for end-of-string since
  156.              * we know that 
  157.              * a) if ibuf is full to the max, then we will
  158.              *    overflow obuf before we hit the end of ibuf.
  159.              * b) if ibuf is not full, then it must contain a
  160.              *    a newline character, but may or may not  
  161.              *    fit into obuf.
  162.              */
  163.             for (;  *iptr != '\n'; ocount++)
  164.             {
  165.                 /* Need space for trailing null */
  166.                 if (ocount >= sizeof(obuf) - 1)
  167.                 {
  168.                     fprintf(stderr, "Output line too long, maximum length is %d.\n", MAXLINE);
  169.                     exit(1);
  170.                 }
  171.                 *optr++ = *iptr++;
  172.             }
  173.             *optr = c;
  174.  
  175.         }
  176.         if (f)
  177.         {
  178.             *optr = '\0';
  179.             puts(obuf);
  180.         }
  181.     }
  182. }
  183.  
  184.  
  185. /*
  186.  * setconcat()
  187.  *
  188.  * Parse the concatination characters and place them in the array c.
  189.  * Return the number of concatination characters.
  190.  *
  191.  * Specials are:
  192.  *    \n    - Newline
  193.  *    \t    - Tab (default)
  194.  *    \    - Backslash
  195.  *    \0    - No concatination character
  196.  */
  197. static int
  198. setconcat(c, in)
  199. char *c;
  200. char *in;
  201. {
  202.     int i;        /* The number seen so far            */
  203.  
  204.     for (i = 0; *in != '\0'; in++, c++, i++)
  205.     {
  206.         if (i > MAXFILES)
  207.         {
  208.             fprintf(stderr, "Too many concatination characters, maximum allowed is %d\n", MAXFILES);
  209.             exit(1);
  210.         }
  211.         if (*in != '\\')
  212.         {
  213.             *c = *in;
  214.             continue;
  215.         }
  216.         in++;
  217.         switch (*in)
  218.         {
  219.            case 'n':
  220.             *c = '\n';
  221.             break;
  222.            case 't':
  223.             *c = '\t';
  224.             break;
  225.            case '0':
  226.             *c = '\0';
  227.             break;
  228.            default:
  229.             /* Includes '\\' */
  230.             *c = *in;
  231.             break;
  232.         }
  233.     }
  234.     return(i);
  235. }
  236.  
  237. static 
  238. prusage()
  239. {
  240.     fprintf(stderr, "USAGE: paste [-s] [-d<list>] files\n");
  241.     exit(1);
  242. }
  243.